package com.demo.webapp.servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.demo.core.model.File;
import com.demo.core.model.Site;
import com.demo.core.service.DocumentService;
import com.demo.security.util.SecurityUtil;
import com.demo.webapp.context.MultisiteContextHolder;

/**
 * 文件上传Servlet
 * 文件存储到DB中
 * 该对象将依赖于CORE包下的File对象和DocumentService服务
 * @author ryuu.kk
 *
 */
public class DBFileUploadServlet extends UploadServlet {

	/**
	 * 版本序列化ID
	 */
	private static final long serialVersionUID = -8671562930413697860L;

	/**
	 * Spring容器上下文
	 */
	protected ApplicationContext applicationContext;
	
	/**
	 * 文档管理服务
	 */
	private static String DOCUMENT_BEAN_NAME = "documentService";
	
	/**
	 * Servlet初始化函数
	 * @param config ServletConfig
	 * @throws ServletException
	 */
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		//取得spring上下文
		applicationContext = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
	}
	
	/**
	 * 写入文件
	 * @param item FileItem
	 * @param request HttpServletRequest
	 * @param index int
	 * @return Object
	 * @throws Exception 异常
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Object writer(FileItem item, HttpServletRequest request, int index) throws Exception {
		
		//这里验证权限,有上传权限
		if (!isPermission()) {
			throw new AccessDeniedException("");
		}
		//生成File模型
		File file = buildFile(item, request.getParameterMap(), index);
		
		DocumentService document = applicationContext.getBean(DOCUMENT_BEAN_NAME, DocumentService.class);
		
		if (!document.folderExists(file.getFolderId())) {
			//不存在该文件夹则提示错误
			//do something...
		};
		return document.createFile(file);
		//document.createFolder(folder)
	}
	
	/**
	 * 创建一个File模型对象
	 * @param item org.apache.commons.fileupload.FileItem
	 * @return File模型
	 * @throws IOException 
	 */
	protected File buildFile(FileItem item, Map<String, Object> params, int index) throws IOException {
		
		String fileName = item.getName();
		//String fieldName = item.getFieldName();
		String contentType = item.getContentType();
		//boolean isInMemory = item.isInMemory();
		long size = item.getSize();
		
		if (fileName.lastIndexOf("\\") >= 0) {
			fileName = fileName.substring(fileName.lastIndexOf("\\"));
		} else {
			fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
		}
		
		String title = fileName;
		
		//创建标题
		Object titObj = params.get("title");
		if (titObj != null) {
			title = (titObj instanceof String[])? ((String[]) titObj)[index] : titObj.toString();
		}
		
		//取得站点ID
		Long siteId = 0L;
		Site site = MultisiteContextHolder.getSite();
		if (site != null) {
			siteId = site.getId();
		}
		
		//取得文件夹
		Long folderId = getFolderId(params, index, null);
		
		File file = new File();
		
		file.setTitle(title);
		file.setSize(size);
		file.setName(fileName);
		file.setContent(item.get());
		file.setContentType(contentType);
		file.setType(File.TYPE_CUSTOM);
		
		file.setEnabled(true);
		file.setSiteId(siteId);
		file.setFolderId(folderId);

		file.setStatus(File.STATUS_NORMAL);
		file.setCreateUser(SecurityUtil.getCurrentUserId());
		file.setModifyUser(SecurityUtil.getCurrentUserId());
		
		return file;
	}
	
	/**
	 * 权限判断
	 * @return 是否有权限
	 */
	protected boolean isPermission() {
		//总是允许
		return true;
	}
	
	/**
	 * 返回文件夹ID
	 * @param params 参数map
	 * @param index 参数索引
	 * @param defaultId 默认目录ID 
	 * @return 目录主键ID
	 */
	protected Long getFolderId(Map<String, Object> params, int index, Long defaultId) {
		String[] forderIds = (String[]) params.get("folderId");
		if (forderIds != null && forderIds.length > index) {
			return Long.parseLong(forderIds[index]);
		}
		return defaultId;
	}
}